package com.fy.fyai.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fy.fyai.common.enums.AiChatConversationStatusEnum;
import com.fy.fyai.common.result.R;
import com.fy.fyai.common.utils.LoginUser;
import com.fy.fyai.controller.vo.AiChatConversationVO;
import com.fy.fyai.model.entity.AiChatConversation;
import com.fy.fyai.service.AiChatConversationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.stream.Collectors;

import static cn.hutool.core.bean.BeanUtil.copyProperties;
import static com.fy.fyai.common.result.R.ok;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;


/**
 * @description: RAG工作接口
 * @author: fwq
 * @date: 2025-10-14
 */
@Tag(name = "AI聊天接口")
@Slf4j
@RestController
@RequestMapping("/aichat")
public class AiChatController {

    @Resource
    private ChatClient chatClient;

    @Resource
    private AiChatConversationService aiChatConversationService;

    /**
     * 创建新会话
     *
     * @return 响应结果
     */
    @Operation(summary = "创建新会话")
    @PostMapping("/newConversation")
    public R createConversation() {
        // 创建新会话
        return ok(aiChatConversationService.createNewConversation(LoginUser.getLoginUserId()));
    }

    /**
     * 获取会话的所有消息
     *
     * @param conversationId 会话ID
     * @return 响应结果
     */
    @Operation(summary = "获取会话的所有消息")
    @GetMapping("/getConversationMessages")
    public R getConversationMessages(@RequestParam String conversationId) {
        return aiChatConversationService.getConversationMessages(conversationId);
    }

    /**
     * 获取会话列表
     *
     * @return 会话列表
     */
    @Operation(summary = "获取会话列表")
    @SaCheckLogin
    @GetMapping("/getConversationList")
    public R getConversationList() {
        return ok(aiChatConversationService.list(new LambdaQueryWrapper<AiChatConversation>()
                        .select(AiChatConversation.class, fileds -> !fileds.getColumn().equals("message_content"))
                        .eq(AiChatConversation::getUserId, LoginUser.getLoginUser().getId())
                        .ne(AiChatConversation::getStatus, AiChatConversationStatusEnum.LOGICAL_DELETED.getCode())
                        .orderByDesc(AiChatConversation::getCreateTime))
                .stream()
                .map(aiChatConversation -> {
                    AiChatConversationVO aiChatConversationVO = new AiChatConversationVO();
                    copyProperties(aiChatConversation, aiChatConversationVO);
                    return aiChatConversationVO;
                }).collect(Collectors.toList()));
    }

    /**
     * AI聊天测试接口（流式版本）
     *
     * @param question 用户问题
     * @return AI流式回复
     */
    @Operation(summary = "聊天接口")
    @GetMapping("/chat")
    public Flux<String> chat(@RequestParam(required = false, defaultValue = "你好") String question,
                             @RequestParam(required = true, defaultValue = "1") String conversationId) {
        return chatClient
                .prompt(question)
                .advisors(chatMemoryConversationIdKey -> chatMemoryConversationIdKey.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId))
                .stream()
                .content();
    }
}
